// 泛型
// 指在定义函数、接口或类的时候，不预先指定具体的类型，
// 而在使用的时候再指定具体类型的一种特性
// function add(val:string|number,y?:string):string{
//   let arr:Array<any>=[];
//   arr.push(val);
//   return arr.join("");
// }

// console.log(add("汤唯"))
// console.log(add(11))
// 泛型的变量  用任意字母代替 用<>放置在函数名后面
// 常用字母 T,U,K,V
// 泛型约束函数
function add<T>(val:T,y:T):Array<T>{
     let arr:Array<T>=[];
     arr.push(val)
     return arr
}
// 泛型的实参 在调用函数时候传递
add<string|number>("德华",2);
add<number>(3,4);
add<boolean>(true,false)
console.log(add<boolean>(true,false))


//多个泛型的形参 
function say<T,U,K>(x:T,y:U,z:K):T|U{
  // unknown 未知类型
  let f:unknown;
  if(typeof x=="number" && typeof y=="number"){
    let fa=x+y;
  }
  let arr=[];
  arr.push(x)
  console.log(x)
  console.log(y)
  console.log(z)
  return x
}
say<number,number,boolean>(88,2,true);
say<string,string,boolean>("1","1",true);
// 泛型约束 接口
interface  Icar<T,U>{
  name:T,
  age:U,
  run(km:T):U
}
// 给接口 传递泛型的参数
let obj1:Icar<string,number>={
  name:"bmw",
  age:88,
  run(km:string){
    return 88
  }
}
interface ICarPlay{
  name:string,
  color:string,
  say(h:string):void
}

// 类的泛型
// 泛型继承了接口 类型

class CarList<T extends ICarPlay,U>{
    name:T;
    color:U;
    constructor(name:T,color:U){
       this.name=name;
       this.color=color;
    } 
    say(h:T){
      
    }
}
// 接口
interface Icar2{
  name:string,
  color:string,
  say(h:string):void
}
// 泛型是实参 可以是接口类型
var benchi=new CarList<ICarPlay,number>({name:"1",color:"1",say(){}},18)
console.log(benchi)
var bmw=new CarList<Icar2,string>({name:"2",color:"2",say(){}},"白色")
console.log(bmw)

// 准备给泛型传递的参数
interface Iu{
   scolor:string
}
var yadi=new CarList<ICarPlay,Iu>({name:"2",color:"2",say(){}},{scolor:"#ccc"});


//在ts使用 获取html元素  常用类型断言
var box=document.getElementById("box") as HTMLDivElement;
box.style.background="green";

var btn=document.getElementById("btn") as HTMLButtonElement;
btn.onclick=function(){
  alert("新年快乐")
}
var con:HTMLElement=document.getElementById("con")
var ccs:NodeList=document.querySelectorAll(".cc")
// 通过declare声明的类型或者变量或者模块，在include包含的文件范围内，
// 都可以直接引用而不用去import或者import type相应的变量或者类型。
declare var $: (selector: string) => any;
// 
$("#box").click(function(){
  alert("今天星期三")
})

// ts的type 和接口类似
// type 是用来创建类型
interface Ihome{
  name:string,
  color:string
}
// type声明还可以定义基础类型、联合类型 或交叉类型。
type mylist=string|number;

// 交叉类型
interface Iface{
  age:number
}
interface Imonth{
  month:string
}
// 交叉类型
let obj3:Iface&Imonth={
  age:11,
  month:"34"
}

type Home ={
  name:string,
  color:string
}
// type可以创建联合类型
type phone=Iface&Imonth;

var myobj:Home={
  name:"哈哈哈",
  color:"字符串"
}
// 经常在ui框架 （elementplus ,vantui ,antd-vue）
//经常导入 type类型 
// import type {phone} from 'element-plus'



